package com.yonyou.crm.sys.modules.ctrl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.yonyou.crm.common.exception.CrmMessageException;
import com.yonyou.crm.common.rest.util.RequestUtil;
import com.yonyou.crm.common.rest.util.ResponseUtil;
import com.yonyou.crm.sys.modules.constants.ClientType;
import com.yonyou.crm.sys.modules.constants.LayoutType;
import com.yonyou.crm.sys.modules.entity.BiztypeRoleVO;
import com.yonyou.crm.sys.modules.entity.BlockItemVO;
import com.yonyou.crm.sys.modules.entity.BlockVO;
import com.yonyou.crm.sys.modules.entity.FieldVO;
import com.yonyou.crm.sys.modules.entity.ItemLayoutItemVO;
import com.yonyou.crm.sys.modules.entity.LayoutAssignmentVO;
import com.yonyou.crm.sys.modules.entity.LayoutCatalogVO;
import com.yonyou.crm.sys.modules.entity.LayoutVO;
import com.yonyou.crm.sys.modules.entity.RelationLayoutVO;
import com.yonyou.crm.sys.modules.rmitf.IBiztypeRmService;
import com.yonyou.crm.sys.modules.rmitf.ILayoutRmService;
import com.yonyou.crm.sys.modules.rmitf.IModuleRmService;
import com.yonyou.crm.sys.role.rmitf.IRoleRmService;
import com.yonyou.iuap.context.InvocationInfoProxy;
@RestController
@RequestMapping(value = "/sys")
public class LayoutCtrl {
	
	@Autowired
	private ILayoutRmService service;
	
	@Autowired
	private IBiztypeRmService biztypeService;
	
	@Autowired
	private  IRoleRmService roleService;
	
	@Autowired
	private IModuleRmService moduleService;
	
	/**
	 * 布局列表
	 * @param objId
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/modules/{objId}/layouts", method = RequestMethod.GET)
	public Object getLayoutList( @PathVariable("objId") Long objId, HttpServletResponse response){

		List<LayoutVO> layouts = service.getLayoutList(objId);
		List<Object> groupList = new ArrayList<Object>();
		Map<Object, Object> groupListMap = new HashMap<Object, Object>();
		for (LayoutVO layout: layouts) {
			Map<String, Object> layoutMap = layoutMapForList(layout);
			String hashKey = layout.getClientType() + "-" + layout.getType();
			if (!groupListMap.containsKey(hashKey)) {
				groupListMap.put(hashKey,new ArrayList<Object>());
			} 
			ArrayList<Object> layoutList = (ArrayList<Object>)groupListMap.get(hashKey);
			layoutList.add(layoutMap);
		}
		
		List<LayoutCatalogVO> layoutCatalogVOs = service.getLayoutCatalogList(objId);
		for( ClientType ct: ClientType.values()) {
			for( LayoutType lt: LayoutType.values()) {
				Map<String,Object> groupMap = new HashMap<String, Object>();
				groupMap.put("name", ct.getName()+lt.getName()+"模板");
				groupMap.put("clientType", ct.getIndex());
				groupMap.put("type", lt.getIndex());
				Map<String, Object> groupWithLayouts = new HashMap<String, Object>();
				groupWithLayouts.put("group", groupMap);
				String groupKey = ct.getIndex() + "-" + lt.getIndex();
				if (groupListMap.containsKey(groupKey)) {
					groupWithLayouts.put("layouts",groupListMap.get(groupKey));
				}	else if (inLayoutCatalog(ct,lt,layoutCatalogVOs)) {
					groupWithLayouts.put("layouts",new ArrayList<Object>());
				} else {
					continue;
				}
				groupList.add(groupWithLayouts);
			}
		}

		JSONObject result = new JSONObject();
		result.put("data", groupList);
		return ResponseUtil.getObject(result);
	}

	/**
	 * 新增模板
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/modules/{objId}/layouts", method = RequestMethod.POST)
	public Object addLayout(@PathVariable("objId") Long objId,
			HttpServletRequest request, HttpServletResponse response){
		JSONObject paramObject = RequestUtil.getParamObject(request);
		LayoutVO layoutVO = new LayoutVO();
		layoutVO.setObjId(objId);
		layoutVO.setBiztypeId(paramObject.getLong("biztypeId"));
		layoutVO.setClientType(paramObject.getInt("clientType"));
		layoutVO.setType(paramObject.getInt("type"));
		layoutVO.setName(paramObject.getString("name"));
		layoutVO.setDescription(paramObject.getString("description"));
		assembleLayout(layoutVO,paramObject) ;
		layoutVO = service.addLayout(layoutVO);
		JSONObject result = new JSONObject();
		Map<String, Object> layoutMap = layoutMapForList(layoutVO);
		result.put("data",layoutMap );
		return ResponseUtil.getObject(result);
	}
	
	/**
	 * 修改模板
	 * @return
	 */
	@RequestMapping(value = "/layouts/{id}", method = RequestMethod.PUT)
	public Object updateLayout(@PathVariable("id") Long id,
			HttpServletRequest request, HttpServletResponse response){
		JSONObject paramObject = RequestUtil.getParamObject(request);
		LayoutVO layoutVO = new LayoutVO();
	    layoutVO.setId(id);
		layoutVO.setName(paramObject.getString("name"));
		layoutVO.setBiztypeId(paramObject.getLong("biztypeId"));
		if(paramObject.containsKey("description")){
			layoutVO.setDescription(paramObject.getString("description"));
		}
		assembleLayout(layoutVO,paramObject) ;
		service.updateLayout(layoutVO);
		layoutVO = service.getLayout(id);
		JSONObject result = new JSONObject();
		Map<String, Object> layoutMap = layoutMapForList(layoutVO);
		result.put("data",layoutMap );
		return ResponseUtil.getObject(result);
	}
	
	/**
	 * 模板详情
	 * @param fullname
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/layouts/{id}", method = RequestMethod.GET)
	public Object getLayout(@PathVariable("id") Long id,
			HttpServletRequest request, HttpServletResponse response){
		LayoutVO layout  = service.getLayout(id);	
		Map<String, Object> resultMap = transformLayoutToMap(layout);
		JSONObject result = new JSONObject();
		Map<String, Object> oprMap = new HashMap<String, Object>();
		oprMap = getOprMap(layout);
		result.put("data", resultMap);
		result.put("operations", oprMap);
		return ResponseUtil.getObject(result);
	}
	
	/**
	 * 模板分配
	 */
	@RequestMapping(value = "/modules/{objId}/layouts/assignment", method = RequestMethod.POST)
	public Object assignLayouts(@PathVariable("objId") Long objId,
			HttpServletRequest request, HttpServletResponse response) {
		JSONObject paramObject = RequestUtil.getParamObject(request);
		Integer clientType = paramObject.getInt("clientType");
		Integer layoutType = paramObject.getInt("layoutType");

		JSONArray assignments = paramObject.getJSONArray("assignments");
		List<LayoutAssignmentVO> layoutAssignmentVOs = new ArrayList<LayoutAssignmentVO>();
		for (int i = 0; i < assignments.size(); i++) {
			LayoutAssignmentVO layoutAssignmentVO = new LayoutAssignmentVO();
			JSONObject assignment = assignments.getJSONObject(i);
			layoutAssignmentVO.setBiztypeId(assignment.getLong("biztypeId"));
			layoutAssignmentVO.setLayoutId(assignment.getLong("layoutId"));
			layoutAssignmentVO.setRoleId(assignment.getLong("roleId"));
			layoutAssignmentVOs.add(layoutAssignmentVO);
		}
		service.assignLayouts(clientType, layoutType,layoutAssignmentVOs);
		return ResponseUtil.getObject();
	}
	
	private void assembleLayout(LayoutVO layoutVO,JSONObject paramObject) {
		JSONArray mainLayout = paramObject.getJSONArray("mainLayout");
		JSONArray itemLayout = paramObject.containsKey("itemLayout") ? paramObject.getJSONArray("itemLayout") : null;
		JSONArray relationLayout =  paramObject.containsKey("relationLayout") ? paramObject.getJSONArray("relationLayout") : null;

		// 处理主对象布局
		List<BlockVO> blockVOList = new ArrayList<BlockVO>();
		for (int i = 0; i < mainLayout.size(); i++) {
			BlockVO blockVO = new BlockVO();
			blockVO.setSortOrder(i);
			JSONObject paramBlock = mainLayout.getJSONObject(i);
			blockVO.setName(paramBlock.getString("name"));
			JSONArray rows = paramBlock.getJSONArray("rows");
			List<BlockItemVO> rowList = new ArrayList<BlockItemVO>();
			for (int j =0;j<rows.size();j++) {
				JSONArray row = rows.getJSONArray(j);
				for (int k =0; k< row.size();k++) {
					JSONObject paramLayoutItem = row.getJSONObject(k);
					BlockItemVO blockItemVO = new BlockItemVO();
					if (paramLayoutItem.getInt("isBlank") == 1) {
						blockItemVO.setIsBlank(1);
						blockItemVO.setApiName("");
						blockItemVO.setName("");
						blockItemVO.setIsReadonly(1);
						blockItemVO.setIsRequired(0);
					} else {
						blockItemVO.setIsBlank(0);
						blockItemVO.setApiName(paramLayoutItem.getString("apiName"));
						blockItemVO.setName(paramLayoutItem.getString("name"));
						blockItemVO.setIsReadonly(paramLayoutItem.getInt("isReadonly"));
						blockItemVO.setIsRequired(paramLayoutItem.getInt("isRequired"));
					}
					blockItemVO.setColumnPosition(k);
					if(paramLayoutItem.containsKey("fieldDefaultValue")){
						blockItemVO.setFieldDefaultValue(paramLayoutItem.getString("fieldDefaultValue"));
					}
					blockItemVO.setRowPosition(j);
					blockItemVO.setWidth(paramLayoutItem.getString("width"));
					blockItemVO.setHeight(paramLayoutItem.getString("height"));
					rowList.add(blockItemVO);
				}
			}
			blockVO.setItems(rowList);
			blockVOList.add(blockVO);
		}
		layoutVO.setMainLayout(blockVOList);

		//处理明细对象布局
		List<ItemLayoutItemVO> itemLayloutItemVOsList = new ArrayList<ItemLayoutItemVO>();
		if (itemLayout != null && itemLayout.size() > 0) {
			for (int i=0;i<itemLayout.size();i++) {
				JSONArray row = itemLayout.getJSONArray(i);
				for (int j=0;j<row.size();j++) {
					JSONObject paramLayoutItem = row.getJSONObject(j);	
					ItemLayoutItemVO itemLayloutItemVO = new ItemLayoutItemVO();
					if (paramLayoutItem.getInt("isBlank") == 1) {
						itemLayloutItemVO.setIsBlank(1);
						itemLayloutItemVO.setApiName("");
						itemLayloutItemVO.setName("");
						itemLayloutItemVO.setIsReadonly(1);
						itemLayloutItemVO.setIsRequired(0);
					} else {
						itemLayloutItemVO.setIsBlank(0);
						itemLayloutItemVO.setApiName(paramLayoutItem.getString("apiName"));
						itemLayloutItemVO.setName(paramLayoutItem.getString("name"));
						itemLayloutItemVO.setIsReadonly(paramLayoutItem.getInt("isReadonly"));
						itemLayloutItemVO.setIsRequired(paramLayoutItem.getInt("isRequired"));
					}
					itemLayloutItemVO.setWidth(paramLayoutItem.getString("width"));
					itemLayloutItemVO.setHeight(paramLayoutItem.getString("height"));
					itemLayloutItemVO.setRowPosition(i);
					itemLayloutItemVO.setColumnPosition(j);
					itemLayloutItemVOsList.add(itemLayloutItemVO);
				}
			}		
			layoutVO.setItemLayout(itemLayloutItemVOsList);
		} else {
			layoutVO.setItemLayout(null);
		}

		// 处理关联对象布局
		if (relationLayout != null && relationLayout.size() > 0) {
			List<RelationLayoutVO> relationLayloutRelationVOsList = new ArrayList<RelationLayoutVO>();
			for (int i = 0; i < relationLayout.size(); i++) {
				Long relObjId = relationLayout.getLong(i);
				RelationLayoutVO relationLayloutRelationVO = new RelationLayoutVO();
				relationLayloutRelationVO.setRelObjId(relObjId);
				relationLayloutRelationVOsList.add(relationLayloutRelationVO);
			}
			layoutVO.setRelationLayout(relationLayloutRelationVOsList);
		} else {
			layoutVO.setRelationLayout(null);
		}	
	}
	
	private Map<String, Object> getOprMap(LayoutVO layout) {
		Map<String, Object> oprMap = new HashMap<String, Object>();
		oprMap.put("edit", 1);
		if (layout.getIsDefault() == 1) {
			oprMap.put("delete", 0);
		} else {
			oprMap.put("delete", 1);
		}
		return oprMap;
	}
	
	/**
	 * 删除模板
	 */
	@RequestMapping(value = "/layouts/{id}", method = RequestMethod.DELETE)
	public Object deleteLayout(@PathVariable("id") Long id,
			HttpServletRequest request, HttpServletResponse response){
		service.deleteLayout(id);
		JSONObject result = new JSONObject();
		return ResponseUtil.getObject(result);
	}
	
	private Map<String, Object> transformLayoutToMap (LayoutVO layoutVO) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		resultMap.put("id", layoutVO.getId());
		resultMap.put("name", layoutVO.getName());
		resultMap.put("clientType", layoutVO.getClientType());
		resultMap.put("type", layoutVO.getType());
		resultMap.put("biztypeId", layoutVO.getBiztypeId());
		resultMap.put("biztypeName", layoutVO.getBiztypeName());
		resultMap.put("description", layoutVO.getDescription());
		//resultMap.put("mainLayout", layoutVO.getMainLayout());
		resultMap.put("mainLayout",mainLayoutToOneDimension(layoutVO));
		resultMap.put("itemLayout", itemLayoutToOneDimension(layoutVO));
		List<RelationLayoutVO> relationLayouts = layoutVO.getRelationLayout();
		List<Long> relObjIds = new ArrayList<Long>();
		if(relationLayouts != null && relationLayouts.size() > 0){
			for(RelationLayoutVO relationLayout :relationLayouts){
				relObjIds.add(relationLayout.getRelObjId());
			}
			resultMap.put("relationLayout", relObjIds);
		}else{
			resultMap.put("relationLayout", relObjIds);
		}
		return resultMap;
	}
	
	private boolean inLayoutCatalog(ClientType ct,LayoutType lt,List<LayoutCatalogVO> layoutCatalogVOs) {
		for (LayoutCatalogVO layoutCatalogVO:layoutCatalogVOs) {
			if (layoutCatalogVO.getClientType() == ct.getIndex() && layoutCatalogVO.getLayoutType() == lt.getIndex()) {
				return true;
			}
		}
		return false;
	}

	private Map<String, Object> layoutMapForList(LayoutVO layout) {
		Map<String, Object> layoutMap = new HashMap<String, Object>();
		Map<String, Object> dataMap = new HashMap<String, Object>();
		Map<String, Object> oprMap = new HashMap<String, Object>();
		dataMap.put("id", layout.getId());
		dataMap.put("tenantId", layout.getTenantId());
		dataMap.put("name", layout.getName());
		dataMap.put("isDefault", layout.getIsDefault());
		dataMap.put("enableState", layout.getEnableState());
		dataMap.put("biztypeId", layout.getBiztypeId());
		dataMap.put("biztypeName", layout.getBiztypeName());
		dataMap.put("description", layout.getDescription());
		dataMap.put("checked", 0);
		oprMap = getOprMap(layout);
		layoutMap.put("data", dataMap);
		layoutMap.put("operations", oprMap);
		return layoutMap;
	}
	
	private List<Map<String, Object>> mainLayoutToOneDimension(LayoutVO layout) {
		List<Map<String, Object>> rsMapList = new ArrayList<Map<String,Object>>();
		List<BlockVO> blockVOs = layout.getMainLayout();
		int i = 0;
		for (BlockVO blockVO: blockVOs) {
			Map<String, Object> blockMap = new HashMap<String, Object>();
			blockMap.put("idForClient", i++);
			blockMap.put("elementType", "group");
			blockMap.put("name", blockVO.getName());
			rsMapList.add(blockMap);
			if (blockVO.getItems() != null) {
				for (BlockItemVO blockItemVO:blockVO.getItems()) {
					Map<String, Object> fieldMap = new HashMap<String, Object>();
					fieldMap.put("idForClient", i++);
					fieldMap.put("elementType", "field");
					fieldMap.put("apiName", blockItemVO.getApiName());
					fieldMap.put("name", blockItemVO.getName());
					fieldMap.put("isReadonly", blockItemVO.getIsReadonly());
					fieldMap.put("isRequired", blockItemVO.getIsRequired());
					fieldMap.put("isBlank", blockItemVO.getIsBlank());
					fieldMap.put("rowPosition", blockItemVO.getRowPosition());
					fieldMap.put("columnPosition", blockItemVO.getColumnPosition());
					fieldMap.put("width",blockItemVO.getWidth());
					fieldMap.put("height", blockItemVO.getHeight());
					if ( blockItemVO.getIsBlank() == 0) {
						FieldVO fieldVO = blockItemVO.getActualField();
						fieldMap.put("fieldType", fieldVO.getType());
					}
					rsMapList.add(fieldMap);
				}
			}	
		}
		return rsMapList;
	}
	
	private List<Map<String, Object>> itemLayoutToOneDimension(LayoutVO layout) {
		List<Map<String, Object>> rsMapList = new ArrayList<Map<String,Object>>();
		List<ItemLayoutItemVO> itemLayoutItemVOs = layout.getItemLayout();
		if (itemLayoutItemVOs == null) {
			return rsMapList;
		}
		int i = 0;
		for (ItemLayoutItemVO itemLayoutItemVO:itemLayoutItemVOs) {
			Map<String, Object> fieldMap = new HashMap<String, Object>();
			fieldMap.put("idForClient", i++);
			fieldMap.put("elementType", "field");
			fieldMap.put("apiName", itemLayoutItemVO.getApiName());
			fieldMap.put("name", itemLayoutItemVO.getName());
			fieldMap.put("isReadonly", itemLayoutItemVO.getIsReadonly());
			fieldMap.put("isRequired", itemLayoutItemVO.getIsRequired());
			fieldMap.put("isBlank", itemLayoutItemVO.getIsBlank());
			fieldMap.put("rowPosition", itemLayoutItemVO.getRowPosition());
			fieldMap.put("columnPosition", itemLayoutItemVO.getColumnPosition());
			fieldMap.put("width",itemLayoutItemVO.getWidth());
			fieldMap.put("height", itemLayoutItemVO.getHeight());
			if ( itemLayoutItemVO.getIsBlank() == 0) {
				FieldVO fieldVO = itemLayoutItemVO.getActualField();
				fieldMap.put("fieldType", fieldVO.getType());
			}
			rsMapList.add(fieldMap);
		}
		return rsMapList;
	}
	
	/**
	 * 相关对象列表
	 * @param objId
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/modules/{objId}/relatedObjects", method = RequestMethod.GET)
	public Object getRelationObjects( @PathVariable("objId") Long objId, HttpServletResponse response){

		List<Map<String, Object>> objects = service.getRelatedObjects(objId);
		JSONObject result = new JSONObject();
		result.put("data", objects);
		return ResponseUtil.getObject(result);
	}
	
	/**
	 * 模板分配模板
	 */
	@RequestMapping(value = "/modules/{objId}/layouts/assignmentTemplate", method = RequestMethod.GET)
	public Object get(@PathVariable("objId") Long objId,
			HttpServletRequest request, HttpServletResponse response) {
		JSONObject paramObject = RequestUtil.getParamObject(request);
		Integer clientType = paramObject.getInt("clientType");
		Integer layoutType = paramObject.getInt("layoutType");
		Map<String, Object> resultMap = service.getAssignmentTemplate(objId, clientType, layoutType);
		return ResponseUtil.getObject(resultMap);
	}
	
	/**
	 * 请求默认模板
	 * @param objId
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/modules/{objId}/layouts/defaultLayout", method = RequestMethod.GET)
	public Object getDefaultLayout(@PathVariable("objId") Long objId,
			HttpServletRequest request, HttpServletResponse response){
		JSONObject paramObject = RequestUtil.getParamObject(request);
		Integer clientType = paramObject.getInt("clientType");
		Integer layoutType = paramObject.getInt("layoutType");
		LayoutVO layOut = service.getDefaultLayout(objId,clientType,layoutType);
		return ResponseUtil.getObject(layOut);
	}
	
	/**
	 * 页面布局停用启用
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/modules/{id}/layouts/status", method = RequestMethod.PUT)
	public Object enableOrDisable(@PathVariable("id") Long id,
			HttpServletRequest request, HttpServletResponse response){
		JSONObject paramObject = RequestUtil.getParamObject(request);
		Integer status = paramObject.getInt("status");
		if (status == 2) {//1代表启用状态，2代表停用状态
			service.disableLayout(id);
		} else {
			service.enableLayout(id);			
		}
		return ResponseUtil.getObject();
	}
	
	/**
	 * 模板分配对应的可选角色列表
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException
	 */
	@RequestMapping(value = "/modules/layouts/roles", method = RequestMethod.GET)
	public Object getAssignRoles(HttpServletRequest request, 
			HttpServletResponse response) throws CrmMessageException{
		JSONObject paramObject = RequestUtil.getParamObject(request);
		Long biztypeId = paramObject.getLong("biztypeId");
		String roleName = paramObject.getString("roleName");
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("biztypeId", biztypeId);
		String tenantIdStr = (String) InvocationInfoProxy.getTenantid();
		Long tenantId = Long.parseLong(tenantIdStr);
		param.put("tenantId", tenantId);
		if(roleName != null && !roleName.equals("")){
			param.put("roleName", roleName);
		}
		
		List<BiztypeRoleVO> biztypeRoleList = service.getAssignRoles(param);
		JSONObject result = new JSONObject();
		result.put("data", biztypeRoleList);
		return ResponseUtil.getObject(result);
	}
}
